<template>
  <div class="player-container">
    <div v-if="isLoading" class="loading-overlay">
      <div class="loading-spinner"></div>
      <p>正在加载...</p>
    </div>

    <div v-if="!isUnlocked" class="unlock-prompt">
      <div class="unlock-modal">
        <h2>需要解锁</h2>
        <p>请先输入解锁码</p>
        <button class="btn btn-primary" @click="$emit('open-unlock')">打开解锁</button>
      </div>
    </div>

    <div v-else class="main-container">
      <header class="header" :class="{ 'electron-header': isElectron }">
        <!-- 窗口控制按钮 -->
        <div class="window-controls">
          <button 
            class="window-button window-button-close" 
            @click="handleWindowClose" 
            @mousedown.stop
            @mouseup.stop
            title="关闭"
          >
            <svg width="11" height="11" viewBox="0 0 12 12">
              <path d="M1 1L11 11M11 1L1 11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
            </svg>
          </button>
          <button 
            class="window-button window-button-minimize" 
            @click="handleWindowMinimize" 
            @mousedown.stop
            @mouseup.stop
            title="最小化"
          >
            <svg width="11" height="11" viewBox="0 0 12 12">
              <path d="M2 6H10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
            </svg>
          </button>
          <button 
            class="window-button window-button-maximize" 
            @click="handleWindowMaximize" 
            @mousedown.stop
            @mouseup.stop
            :title="isMaximized ? '还原' : '最大化'"
          >
            <svg v-if="!isMaximized" width="11" height="11" viewBox="0 0 12 12">
              <rect x="2" y="2" width="8" height="8" stroke="currentColor" stroke-width="1.5" fill="none"/>
            </svg>
            <svg v-else width="11" height="11" viewBox="0 0 12 12">
              <path d="M2 4H6V2M8 2V6H10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none"/>
              <path d="M10 8H6V10M4 10V6H2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none"/>
            </svg>
          </button>
        </div>
        <div class="logo-title">
          <canvas ref="headerLogo" width="40" height="40"></canvas>
          <h1>FLAC 音乐播放器</h1>
        </div>
        <div class="header-actions">
          <button class="icon-btn" title="刷新" @click="handleRefresh">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M23 4v6h-6M1 20v-6h6M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"></path>
            </svg>
          </button>
        </div>
      </header>

      <div class="content">
        <div class="search-bar">
          <form @submit.prevent="handleSearch">
            <input 
              v-model="searchKeyword"
              type="text" 
              placeholder="搜索歌曲/歌手/专辑" 
              autocomplete="off" 
            />
            <button type="submit" class="icon-btn" title="搜索">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <circle cx="11" cy="11" r="8"></circle>
                <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
              </svg>
            </button>
          </form>
        </div>

        <div 
          ref="listContainer"
          :class="['list-container', { empty: isEmpty }]"
          @scroll="handleScroll"
        >
          <div v-if="isLoadingFirst" class="list-loading">加载中...</div>
          <div v-if="hasError" class="list-error">加载失败，请重试</div>
          <ul v-if="!isEmpty || isLoadingFirst" class="result-list">
            <li v-if="isLoadingFirst" v-for="i in 8" :key="`skeleton-${i}`" class="skeleton-item">
              <div class="skeleton-cover"></div>
              <div class="skeleton-lines">
                <div class="skeleton-line"></div>
                <div class="skeleton-line short"></div>
              </div>
              <div class="skeleton-line short"></div>
            </li>
            <li 
              v-for="item in resultItems" 
              :key="item.id" 
              class="result-item"
              @click="playItem(item)"
            >
              <img 
                v-if="item.cover" 
                :src="item.cover" 
                class="result-cover"
                @error="handleImageError"
              />
              <div v-else class="result-cover no-cover"></div>
              <div class="result-meta">
                <div class="title">{{ escapeHtml(item.title || '未知标题') }}</div>
                <div class="subtitle">
                  {{ escapeHtml(item.artist || '') }}{{ item.album ? ' · ' + escapeHtml(item.album) : '' }}
                </div>
              </div>
              <div class="duration">{{ item.duration || '' }}</div>
            </li>
            <li v-if="isLoadingMore" class="loading-footer">加载中...</li>
          </ul>
        </div>

        <div class="player-bar">
          <div class="now-playing">
            <span v-if="currentTrack">
              {{ currentTrack.title || '未知标题' }}{{ currentTrack.artist ? ' - ' + currentTrack.artist : '' }}
            </span>
            <span v-else>未在播放</span>
          </div>
          <audio 
            ref="audioElement"
            controls 
            preload="none"
            @error="handleAudioError"
          ></audio>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { storage } from '../utils/storage.js'
import { searchTracks, resolveStream } from '../utils/api.js'
import '../utils/logo-generator.js'

const props = defineProps({
  isElectron: {
    type: Boolean,
    default: false
  },
  isMaximized: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['open-unlock', 'window-minimize', 'window-maximize', 'window-close'])

const headerLogo = ref(null)
const listContainer = ref(null)
const audioElement = ref(null)
const searchKeyword = ref('')
const isUnlocked = ref(false)
const isLoading = ref(true)
const isLoadingFirst = ref(false)
const isLoadingMore = ref(false)
const hasError = ref(false)
const resultItems = ref([])
const currentTrack = ref(null)

// 分页状态
let currentKeyword = ''
let currentPage = 0
const pageSize = 30
let isLoadingState = false
let hasMore = true

const isEmpty = computed(() => {
  return !isLoadingFirst.value && !hasError.value && resultItems.value.length === 0
})

// 生成 header logo
onMounted(async () => {
  try {
    if (headerLogo.value && window.logoGenerator) {
      const result = await storage.get(['headerLogoDataUrl'])
      let logoDataUrl = result.headerLogoDataUrl
      
      if (!logoDataUrl) {
        logoDataUrl = window.logoGenerator.generateLogo(40)
        await storage.set({ headerLogoDataUrl: logoDataUrl })
      }
      
      if (logoDataUrl) {
        const img = new Image()
        img.onload = () => {
          const ctx = headerLogo.value.getContext('2d')
          ctx.drawImage(img, 0, 0)
        }
        img.src = logoDataUrl
      }
    }
  } catch (error) {
    console.error('Logo error:', error)
  }

  // 检查 window.electronAPI 是否可用
  if (window.electronAPI) {
    console.log('window.electronAPI available:', {
      hasWindow: !!window.electronAPI.window,
      hasMinimize: typeof window.electronAPI.window?.minimize === 'function',
      hasMaximize: typeof window.electronAPI.window?.maximize === 'function',
      hasClose: typeof window.electronAPI.window?.close === 'function'
    })
  } else {
    console.warn('window.electronAPI not available')
  }

  checkUnlockStatus()
})

// 检查解锁状态
async function checkUnlockStatus() {
  try {
    const result = await storage.get(['unlockCode', 'unlockTime', 'isUnlocked'])
    let unlocked = false
    
    if (result.isUnlocked && result.unlockTime) {
      const unlockTime = result.unlockTime
      const elapsed = Date.now() - unlockTime
      const remaining = 12 * 60 * 60 * 1000 - elapsed
      unlocked = remaining > 0
    }
    
    if (unlocked) {
      isUnlocked.value = true
    } else {
      isUnlocked.value = false
      if (result.unlockTime) {
        await storage.remove(['unlockCode', 'unlockTime', 'isUnlocked'])
      }
    }
  } catch (error) {
    console.error('Check unlock error:', error)
    isUnlocked.value = false
  } finally {
    isLoading.value = false
  }
  
  // 监听存储变化
  storage.onChanged((changes, namespace) => {
    if (namespace === 'local' && changes.isUnlocked) {
      if (changes.isUnlocked.newValue) {
        isUnlocked.value = true
      } else {
        isUnlocked.value = false
      }
    }
  })
}

// 刷新
function handleRefresh() {
  searchKeyword.value = ''
  renderEmpty()
}

// 搜索
function handleSearch() {
  const keyword = searchKeyword.value.trim()
  if (!keyword) {
    resetPaging()
    renderEmpty()
    return
  }
  startSearch(keyword)
}

// 开始搜索
function startSearch(keyword) {
  resetPaging()
  currentKeyword = keyword
  resultItems.value = []
  loadNextPage()
}

// 加载下一页
async function loadNextPage() {
  if (!currentKeyword || isLoadingState || !hasMore) return
  
  isLoadingState = true
  
  const nextPage = currentPage + 1
  
  if (nextPage === 1) {
    isLoadingFirst.value = true
    hasError.value = false
  } else {
    isLoadingMore.value = true
  }
  
  try {
    const items = await searchTracks(currentKeyword, nextPage, pageSize)
    
    if (items.length === 0 && nextPage === 1) {
      resultItems.value = []
      hasMore = false
    } else {
      if (nextPage === 1) {
        resultItems.value = items
      } else {
        resultItems.value.push(...items)
      }
      hasMore = items.length >= pageSize
      currentPage = nextPage
    }
    
    isLoadingFirst.value = false
    hasError.value = false
  } catch (error) {
    console.error('Search error:', error)
    hasError.value = true
    isLoadingFirst.value = false
  } finally {
    isLoadingState = false
    isLoadingMore.value = false
  }
}

// 滚动处理
function handleScroll() {
  if (!currentKeyword || isLoadingState || !hasMore) return
  
  const container = listContainer.value
  if (!container) return
  
  const threshold = 120
  const reachedBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - threshold
  
  if (reachedBottom) {
    loadNextPage()
  }
}

// 播放项目
async function playItem(item) {
  if (!audioElement.value) return
  
  currentTrack.value = item
  
  if (item.url) {
    audioElement.value.src = item.url
    audioElement.value.play().catch(handleAudioError)
    return
  }
  
  try {
    const result = await resolveStream(item.detailUrl, item.id, item.platform)
    
    if (!result.url) {
      if (result.needUnlock) {
        isUnlocked.value = false
        emit('open-unlock')
      } else {
        handleAudioError()
      }
      return
    }
    
    audioElement.value.src = result.url
    audioElement.value.play().catch(handleAudioError)
  } catch (error) {
    console.error('Play error:', error)
    handleAudioError()
  }
}

// 音频错误处理
function handleAudioError() {
  if (audioElement.value) {
    audioElement.value.pause()
    audioElement.value.removeAttribute('src')
  }
  if (currentTrack.value) {
    currentTrack.value = { ...currentTrack.value, title: '播放失败，可能因为版权原因无法播放，请换一首歌播放' }
  }
}

// 图片错误处理
function handleImageError(event) {
  const img = event.target
  const placeholder = document.createElement('div')
  placeholder.className = 'result-cover no-cover'
  img.replaceWith(placeholder)
}

// 转义 HTML
function escapeHtml(str) {
  return String(str).replace(/[&<>"]/g, (s) => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[s]))
}

// 渲染空状态
function renderEmpty() {
  resultItems.value = []
  hasError.value = false
  isLoadingFirst.value = false
  resetPaging()
}

// 重置分页
function resetPaging() {
  currentKeyword = ''
  currentPage = 0
  isLoadingState = false
  hasMore = true
}

// 窗口控制函数
function handleWindowMinimize(e) {
  if (e) {
    e.preventDefault()
    e.stopPropagation()
  }
  
  // 直接通过事件传递给父组件处理
  emit('window-minimize')
}

function handleWindowMaximize(e) {
  if (e) {
    e.preventDefault()
    e.stopPropagation()
  }
  
  // 直接通过事件传递给父组件处理
  emit('window-maximize')
}

function handleWindowClose(e) {
  if (e) {
    e.preventDefault()
    e.stopPropagation()
  }
  
  // 直接通过事件传递给父组件处理
  emit('window-close')
}
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.player-container {
  width: 100%;
  height: 100%;
  min-height: calc(100vh - 40px);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
  background: #f7f7f2;
  color: #1a1a1a;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  -webkit-app-region: no-drag;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #f7f7f2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  transition: opacity 0.3s ease;
}

.loading-spinner {
  width: 50px;
  height: 50px;
  border: 4px solid rgba(0, 0, 0, 0.06);
  border-top-color: #667eea;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 20px;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loading-overlay p {
  font-size: 16px;
  opacity: 0.8;
}

.main-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
}

.header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 15px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
  z-index: 100;
  position: relative;
  min-height: 60px;
  overflow: visible;
}

/* Electron 环境下的沉浸式头部 */
.header.electron-header {
  -webkit-app-region: drag;
  padding-left: 12px;
  padding-right: 12px;
}

.header.electron-header .logo-title {
  -webkit-app-region: drag;
}

.header.electron-header .window-controls {
  -webkit-app-region: no-drag !important;
}

.header.electron-header .header-actions {
  -webkit-app-region: no-drag;
}

/* 窗口控制按钮 */
.window-controls {
  display: flex !important;
  align-items: center;
  gap: 8px;
  margin-right: 16px;
  -webkit-app-region: no-drag;
  position: relative;
  z-index: 10000;
  flex-shrink: 0;
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

.window-button {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.15s ease;
  padding: 0;
  margin: 0;
  position: relative;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  background: #ffffff;
  pointer-events: auto;
  user-select: none;
  -webkit-user-select: none;
}

.window-button:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
}

.window-button:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}


.window-button-close {
  background: #ff5f57;
  border-color: rgba(0, 0, 0, 0.2);
}

.window-button-close:hover:not(:disabled) {
  background: #ff3b30;
}

.window-button-minimize {
  background: #ffbd2e;
  border-color: rgba(0, 0, 0, 0.2);
}

.window-button-minimize:hover:not(:disabled) {
  background: #ff9500;
}

.window-button-maximize {
  background: #28c840;
  border-color: rgba(0, 0, 0, 0.2);
}

.window-button-maximize:hover:not(:disabled) {
  background: #1fb832;
}

.window-button svg {
  width: 11px;
  height: 11px;
  pointer-events: none;
  stroke: rgba(0, 0, 0, 0.8);
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.logo-title {
  display: flex;
  align-items: center;
  gap: 15px;
  flex: 1;
  -webkit-app-region: drag;
  padding-left: 8px;
}

.logo-title canvas {
  flex-shrink: 0;
}

#header-logo {
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.header h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: #ffffff;
}

.header-actions {
  display: flex;
  gap: 10px;
  -webkit-app-region: no-drag;
  flex-shrink: 0;
}

.header .icon-btn {
  background: rgba(255, 255, 255, 0.15);
  color: #ffffff;
}

.header .icon-btn:hover {
  background: rgba(255, 255, 255, 0.25);
}

.icon-btn {
  width: 40px;
  height: 40px;
  border: none;
  background: rgba(0, 0, 0, 0.06);
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #1a1a1a;
  transition: all 0.3s ease;
}

.icon-btn:hover {
  background: rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.icon-btn:active {
  transform: translateY(0);
}

.content {
  flex: 1;
  overflow: hidden;
  position: relative;
  background: linear-gradient(180deg, #faf9f5 0%, #f4f2ed 100%);
}

.search-bar {
  padding: 14px 20px;
  background: #ffffff;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.search-bar form {
  display: flex;
  gap: 10px;
}

.search-bar input {
  flex: 1;
  height: 40px;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  background: #ffffff;
  color: #1a1a1a;
  outline: none;
}

.search-bar input::placeholder {
  color: rgba(0, 0, 0, 0.4);
}

.list-container {
  position: absolute;
  top: 70px;
  bottom: 80px;
  left: 0;
  right: 0;
  overflow: auto;
  padding: 10px 20px;
  background: transparent;
}

.list-container.empty::before {
  content: "♪";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 120px;
  line-height: 1;
  color: #8a7ff3;
  opacity: 0.08;
  pointer-events: none;
}

.list-loading, .list-error {
  text-align: center;
  opacity: 0.7;
  margin-top: 40px;
}

.list-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: rgba(0, 0, 0, 0.68);
  margin-top: 8px;
  padding: 6px 12px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.035);
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.list-loading::before {
  content: "";
  width: 24px;
  height: 24px;
  border: 3px solid rgba(0, 0, 0, 0.12);
  border-top-color: #667eea;
  border-right-color: #8a7ff3;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.result-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 72px;
}

.skeleton-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border-radius: 10px;
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.skeleton-cover {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  background: linear-gradient(90deg, #efeee9 25%, #e9e7e2 37%, #efeee9 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}

.skeleton-lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.skeleton-line {
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg, #efeee9 25%, #e9e7e2 37%, #efeee9 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}

.skeleton-line.short {
  width: 60%;
}

@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.result-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border-radius: 10px;
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.06);
  cursor: pointer;
  transition: background 0.2s ease;
}

.result-item:hover {
  background: #fafafa;
}

.result-cover {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  background: #f0f0f0;
  object-fit: cover;
  display: block;
}

.result-cover.no-cover {
  background: linear-gradient(135deg, #eceae6 0%, #f7f6f2 100%);
  border: 1px dashed rgba(0, 0, 0, 0.12);
}

.result-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.title {
  font-weight: 600;
}

.subtitle {
  font-size: 12px;
  opacity: 0.7;
}

.duration {
  font-size: 12px;
  opacity: 0.8;
}

.loading-footer {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 6px 12px 12px;
  color: rgba(0, 0, 0, 0.68);
}

.loading-footer::before {
  content: "";
  width: 24px;
  height: 24px;
  border: 3px solid rgba(0, 0, 0, 0.12);
  border-top-color: #667eea;
  border-right-color: #8a7ff3;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.player-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 70px;
  padding: 12px 20px;
  background: #ffffff;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 16px;
  z-index: 1000;
}

.now-playing {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.9;
}

.player-bar audio {
  width: 520px;
  max-width: 54vw;
}

.unlock-prompt {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  backdrop-filter: blur(10px);
}

.unlock-modal {
  background: #ffffff;
  padding: 40px 50px;
  border-radius: 16px;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.08);
  max-width: 400px;
}

.unlock-modal h2 {
  font-size: 24px;
  margin-bottom: 15px;
  font-weight: 600;
}

.unlock-modal p {
  font-size: 16px;
  opacity: 0.9;
  margin-bottom: 30px;
  line-height: 1.6;
}

.btn {
  padding: 14px 30px;
  font-size: 16px;
  font-weight: 600;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-family: inherit;
}

.btn-primary {
  background: #667eea;
  color: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.btn-primary:hover {
  background: #5a62e5;
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
}

.btn-primary:active {
  transform: translateY(0);
}
</style>

